'''
Created on 09.10.2009

@author: theman
'''
from django.db.models import permalink, signals, permalink
from google.appengine.ext import db
from django.core.urlresolvers import reverse
from bvuserapp.models import User
from django.utils.translation import ugettext_lazy
from ragendja.dbutils import get_object,get_object_list
from django.db.models.signals import pre_save, pre_delete, post_save
from ragendja.dbutils import cleanup_relations
from django.core.urlresolvers import reverse
import logging
from django.core.cache import cache
from google.appengine.ext.db import Key
class Tag(db.Model):
    tag = db.StringProperty(verbose_name=ugettext_lazy('Tag name')) 
    count = db.IntegerProperty(verbose_name=ugettext_lazy('Count of tags in current namespace'), default=0)
    namespace = db.StringProperty(verbose_name=ugettext_lazy('Namespace'), default='default')

signals.pre_delete.connect(cleanup_relations, sender=Tag)



class BlogPost(db.Model):
    
    author = db.ReferenceProperty(User, verbose_name=ugettext_lazy('Name of author'), collection_name='posts')
    author_username = db.StringProperty(verbose_name=ugettext_lazy('Author\'s username'))
    tags = db.StringProperty(verbose_name=ugettext_lazy('Tags'))
    title = db.StringProperty(verbose_name=ugettext_lazy('Title'))
    text = db.TextProperty(verbose_name=ugettext_lazy('Content'))
    created_at = db.DateTimeProperty(verbose_name=ugettext_lazy('Created at'), auto_now=False, auto_now_add=True)
    saved_at = db.DateTimeProperty(verbose_name=ugettext_lazy('Updated at'), auto_now=True, auto_now_add=False)
    comments_count = db.IntegerProperty(verbose_name=ugettext_lazy('Comments count'), default=0)
    is_private = db.BooleanProperty(verbose_name=ugettext_lazy('Analysis is private'), default=False)
   
    def save_tags(self):        
        if self.tags is None or self.tags == '':
            return
        tags_as_string = list(set(filter(lambda x: x != '', map(lambda x: x.strip().lower(), self.tags.split(',')))))
        tags_as_string.sort()
        
        self.tags = ', '.join(tags_as_string)
        self.put()
        
        namespace = self.author_username
        tags = []
        posttags = []
        for tag_as_string in tags_as_string:
            tag = get_object(Tag, 'tag = ', tag_as_string, 'namespace = ', namespace) or Tag(tag=tag_as_string, namespace=namespace)
            if not tag.is_saved(): tag.put()        
            tag.count += 1
            tags.append(tag)
            posttags.append(PostTag(tag=tag, post=self))

        db.put(tags)
        db.put(posttags)
        return len(tags_as_string)
        

        
    def _decr_count_of_old_tags(self,old_tags=''):
        namespace = self.author_username
        tags = []
        old_tags = filter(lambda x: x != '', map(lambda x: x.strip().lower(), old_tags.split(',')))
        logging.debug('BlogPost.delete_tags: tags=%s' % tags)
        for old_tag in old_tags:
            tag = get_object(Tag, 'tag = ', old_tag, 'namespace = ', namespace) or Tag(tag=old_tag, namespace=namespace)
            tag.count = tag.count-1 if tag.count>0 else 0
            if not tag.is_saved(): tag.put()
            tags.append(tag)
            
        db.put(tags)
        logging.debug('BlogPost.delete_tags: put in db=%s' % tags)
        return len(tags) # count of processed tags

    def _clean_posttags(self):
        objs = get_object_list(PostTag, ' post = ', self)
        logging.debug('BlogPost._clean_posttags: objs=%s' % list(objs))
        db.delete(objs)
        return len(list(objs))

    def update_old_tags(self, old_tags):
        self._clean_posttags()
        self._decr_count_of_old_tags(old_tags)

    def __unicode__(self):
        return '%s %s' % (self.created_at, self.author)
    
    @permalink
    def get_absolute_url(self):
        return ('blog_post_read', (), {'username': self.author_username, 'post_key': self.key().id()})
    
    def can_edit_by(self, user):
        result = False
        if user.is_staff or self.author == user:
            result = True         
        return result
    
    def tags_urls(self):  
              
        tags_list = map(lambda x: x.strip().lower(), self.tags.split(','))

        tags_urls = []
        for tag in tags_list:
            tags_urls.append('<a href="%s">%s</a>' % (reverse('search_by_tag', args=(self.author_username,tag)), tag))
        logging.debug(', '.join(tags_urls))
        return ', '.join(tags_urls)
    
    

signals.pre_delete.connect(cleanup_relations, sender=BlogPost)



class PostTag(db.Model):
    tag = db.ReferenceProperty(Tag, verbose_name=ugettext_lazy('Tag')) 
    post = db.ReferenceProperty(BlogPost, verbose_name=ugettext_lazy('Post'))
    created_at = db.DateTimeProperty(verbose_name=ugettext_lazy('Created at'), auto_now=False, auto_now_add=True)



class PostComment(db.Model):
    
    post = db.ReferenceProperty(BlogPost, verbose_name=ugettext_lazy('Post'), collection_name='comments')
    author = db.ReferenceProperty(User, verbose_name=ugettext_lazy('Name of author'), collection_name='comments')
    created_at = db.DateTimeProperty(verbose_name=ugettext_lazy('Created at'), auto_now=False, auto_now_add=True)
    text = db.TextProperty(verbose_name=ugettext_lazy('Content'))
   
    def can_deleted_by(self, user):
        result = False
        if user.is_staff or self.author == user or self.post.author == user:
            result = True         
        return result



def increment_post_comments_count(sender, **kwargs):
    if kwargs.has_key('instance'):
        comment = kwargs['instance']
        post = comment.post
        comments_count = post.comments_count or 0 
        post.comments_count = comments_count + 1
        post.save()
        cache.delete('%s_%s' % (post.author_username, post.key().id()))

def decrement_post_comments_count(sender, **kwargs):
    if kwargs.has_key('instance'):
        comment = kwargs['instance']
        post = comment.post
        comments_count = post.comments_count or 0 
        post.comments_count = comments_count - 1 if comments_count>0 else 0
        post.save()
        cache.delete('%s_%s' % (post.author_username, post.key().id()))        
        
pre_save.connect(increment_post_comments_count, sender=PostComment)
pre_delete.connect(decrement_post_comments_count, sender=PostComment)


